/* 
 * Copyright 2012 Samuel Mello
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; version 2 or later of the License.
 * 
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 * 
 */

package datasoul.render.vlcj;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JOptionPane;
import javax.swing.JWindow;

import uk.co.caprica.vlcj.player.MediaPlayer;
import uk.co.caprica.vlcj.player.MediaPlayerEventAdapter;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;

import com.sun.jna.Platform;

import datasoul.DatasoulMainForm;
import datasoul.config.BackgroundConfig;
import datasoul.config.ConfigObj;
import datasoul.render.ContentManager;
import datasoul.serviceitems.ServiceItemTable;
import datasoul.util.ObjectManager;

/**
 *
 * @author samuel
 */
public class VlcjBackgroundFrame extends javax.swing.JFrame {
    
    /**
	 * 
	 */
	private static final long serialVersionUID = 8030486478069411461L;
	
	private MediaPlayerFactory factory;
    private EmbeddedMediaPlayer mediaPlayer;
    private boolean playingItem;
    private JWindow overlayWindow;
    private boolean handlingErrors;
    
    /**
     * Creates new form VlcjBackgroundFrame
     */
    public VlcjBackgroundFrame() {
        initComponents();
        DatasoulMainForm.setDatasoulIcon(this);
        String[] args;
        if (Platform.isMac()){
            args = new String[] {"--no-video-title-show", "--vout=macosx"};
        }else{
            args = new String[] {"--no-video-title-show"};
        }
        factory = new MediaPlayerFactory(args);
        mediaPlayer = factory.newEmbeddedMediaPlayer(null);
        mediaPlayer.addMediaPlayerEventListener(new MediaPlayerControl());
        Canvas c = new Canvas();
        this.getContentPane().setLayout(new BorderLayout());
        this.getContentPane().add(c, BorderLayout.CENTER);
        c.setBackground(Color.black);
        mediaPlayer.setVideoSurface(factory.newVideoSurface(c));
    }
    
    public void handleErrors(){
        if (!handlingErrors){
            addWindowListener(new VlcjBackgroundFrameWindowAdapter());
            handlingErrors = true;
        }
    }

    public void setOverlay(JWindow win){
        overlayWindow = win;
    }
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setUndecorated(true);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    public void registerAsMain(){
        this.setBounds(ConfigObj.getActiveInstance().getMainOutputDeviceObj().getBounds());
        overlayWindow.setBounds(ConfigObj.getActiveInstance().getMainOutputDeviceObj().getBounds());
    }
        

    public void registerAsMonitor(){
        this.setBounds(ConfigObj.getActiveInstance().getMonitorOutputDeviceObj().getBounds());
        overlayWindow.setBounds(ConfigObj.getActiveInstance().getMonitorOutputDeviceObj().getBounds());
    }

    private String getLiveURL(){
        if (Platform.isLinux()){
            return "v4l2://";
        }
        if (Platform.isWindows()){
            return "dshow://";
        }
        if (Platform.isMac()){
            return "qtcapture://";
        }
        return null;
    }
    
    /*
     * This method is responsible for setting the appropriate background when a item stop playing
     */
    public void playBackground(){
        int mode = BackgroundConfig.getInstance().getModeAsInt();
        switch (mode){
            case BackgroundConfig.MODE_STATIC:
                mediaPlayer.stop();
                break;
            case BackgroundConfig.MODE_VIDEO:
                mediaPlayer.playMedia(BackgroundConfig.getInstance().getVideoFile(), "no-audio");
                break;
            case BackgroundConfig.MODE_LIVE:
                String url = getLiveURL();
                if (url != null){
                    mediaPlayer.playMedia(url, "no-audio");
                }
                break;
        }
    }
    
    /*
     * Called to play a Video Item
     */
    public void playVideoItem(String path){
        playingItem = true;
        if (BackgroundConfig.getInstance().getModeAsInt() == BackgroundConfig.MODE_STATIC){
            ContentManager.getInstance().setMainShowBackground(false);
        }
        ContentManager.getInstance().slideChange(-1);
        mediaPlayer.playMedia(path);
    }
    
    /* 
     * Force stop for a video item
     */
    public void stopVideoItem(){
        if (playingItem){
            mediaPlayer.stop();
            playBackground();
        }
    }
    
    /* 
     * Pause a Video Item
     */
    public void pauseVideoItem(){
        if (playingItem){
            mediaPlayer.pause();
        }
    }
    
    public void seekVideoItem(float position){
        if (playingItem){
            mediaPlayer.setPosition(position);
        }
    }
    
    private ServiceItemTable getLiveTable(){
        return ObjectManager.getInstance().getLivePanel().getLiveServiceItemTable();
    }
    
    /**
     * Called to clean up after video item finished
     */
    public void videoItemCompleted(){
        playingItem = false;
        if (BackgroundConfig.getInstance().getModeAsInt() == BackgroundConfig.MODE_STATIC){
            ContentManager.getInstance().setMainShowBackground(true);
        }
        ContentManager.getInstance().slideChange(-1);
        getLiveTable().notifyVideoEnd();
    }
    
    private class MediaPlayerControl extends MediaPlayerEventAdapter {

        @Override
        public void error(MediaPlayer mp) {
            JOptionPane.showMessageDialog(ObjectManager.getInstance().getDatasoulMainForm(), 
                    java.util.ResourceBundle.getBundle("datasoul/internationalize").getString("ERROR PLAYING VIDEO"), "Datasoul", JOptionPane.ERROR_MESSAGE);
        }

        @Override
        public void playing(MediaPlayer mp) {
            getLiveTable().videoPausedChanged(false);
        }

        @Override
        public void paused(MediaPlayer mp) {
            getLiveTable().videoPausedChanged(true);
        }

        @Override
        public void finished(MediaPlayer mp) {
            if (playingItem){
                videoItemCompleted();
                getLiveTable().videoPausedChanged(true);
            }
            playBackground();
        }

        @Override
        public void positionChanged(MediaPlayer mp, float f) {
            getLiveTable().videoPositionChanged(f);
        }

        @Override
        public void pausableChanged(MediaPlayer mp, int i) {
            getLiveTable().videoPausableChanged(i != 0);
        }

    }
    
    
    private class VlcjBackgroundFrameWindowAdapter extends WindowAdapter{
        @Override
        public void windowActivated(WindowEvent e) {
            overlayWindow.toFront();
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
